package com.ce.cetag.util;

import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.jsp.JspWriter;

/**
 *
 *<p>中企动力</p>
 *@author <a href="mailto:shaibiao@yahoo.com.cn">��˧��贺帅彪</a>
 *
 * @create date : 2007-7-27
 */
public class MarkupWriterImpl {

	private Writer _jspWriter;

	private boolean _openTag = false;

	private boolean _emptyTag = false;

	private List _activeElementStack;

	public MarkupWriterImpl(JspWriter writer) {

		_jspWriter = writer;

	}

	public MarkupWriterImpl(StringWriter writer) {

		_jspWriter = writer;
	}

	public void responsePrint(String str) {

		try {
			_jspWriter.write(str);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void responsePrint(int str) {
		try {
			_jspWriter.write(str);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void responsePrint(char str) {
		try {
			_jspWriter.write(str);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void responsePrint(Object str) {
		try {
			_jspWriter.write(str.toString());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void responsePrintln(String str) {
		try {
			_jspWriter.write("\r\n" + str);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void attribute(String name, int value) {
		checkTagOpen();

		responsePrint(' ');
		responsePrint(name);
		responsePrint("=\"");
		responsePrint(value);
		responsePrint('"');
	}

	public void attribute(String name, boolean value) {
		checkTagOpen();

		responsePrint(' ');
		responsePrint(name);
		responsePrint("=\"");
		responsePrint(value);
		responsePrint('"');
	}

	public void attribute(String name, String value) {
		attribute(name, value, false);
	}

	public void attribute(String name, String value, boolean raw) {
		checkTagOpen();

		responsePrint(' ');

		responsePrint(name);
		responsePrint("=\"");

		maybePrintFiltered(value);

		responsePrint('"');
	}

	private void maybePrintFiltered(String data) {
		if (data == null)
			return;

		responsePrint(data.toString());
		return;

	}

	public void begin(String name) {
		if (_openTag)
			closeTag();

		push(name);

		responsePrint('<');
		responsePrint(name);

		_openTag = true;
		_emptyTag = false;
	}

	public void beginEmpty(String name) {
		if (_openTag)
			closeTag();

		responsePrint('<');
		responsePrint(name);

		_openTag = true;
		_emptyTag = true;
	}

	public void close() {
		if (_openTag)
			closeTag();

		// Close any active elements.

		while (!stackEmpty()) {
			responsePrint("</");
			responsePrint(pop());
			responsePrint('>');
		}

		try {
			_jspWriter.close();
		} catch (IOException e) {
			e.printStackTrace();
		}

		_jspWriter = null;
		_activeElementStack = null;
	}

	public void closeTag() {
		if (_emptyTag)
			responsePrint('/');

		responsePrint('>');

		_openTag = false;
		_emptyTag = false;
	}

	public void comment(String value) {
		if (_openTag)
			closeTag();

		responsePrint("<!-- ");
		responsePrint(value);
		responsePrintln(" -->");
	}

	public void end() {
		if (_openTag)
			closeTag();

		responsePrint("</");
		responsePrint(pop());
		responsePrint('>');
		flush();

	}

	public void end(String name) {
		if (_openTag)
			closeTag();

		while (true) {
			String tagName = pop();

			responsePrint("</");
			responsePrint(tagName);
			responsePrint('>');

			if (tagName.equals(name))
				break;
		}
		flush();
	}

	public void flush() {

	}

	public void print(String value) {
		if (_openTag)
			closeTag();

		responsePrint(value);
	}

	public void println() {
		if (_openTag)
			closeTag();

		responsePrintln("");
	}

	private void checkTagOpen() {
		if (!_openTag)
			throw new IllegalStateException("tag not open");
	}

	private void push(String name) {
		if (_activeElementStack == null)
			_activeElementStack = new ArrayList();

		_activeElementStack.add(name);
	}

	private String pop() {
		int lastIndex = _activeElementStack.size() - 1;

		return (String) _activeElementStack.remove(lastIndex);
	}

	private boolean stackEmpty() {
		return _activeElementStack == null || _activeElementStack.isEmpty();
	}

}